
//
// 20120825 - AH - Created.
// 20120906 - AH - Missing java doc.
// 20120908 - AH - show(TestForestFactory, boolean).
// 20121001 - AH - Stopped performing tests in a depth first search sequence
//                 but performs all paths from roots to all leafs independently.
// 20121111 - AH - Support for multiple worlds: Moved all GUI that has to do
//                 with running tests to TestTreeManagerPanel and create in tabs
//                 of such panels, each to run the tests for one world.
//

package org.japril.jhut.swing;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.util.List;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JTabbedPane;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;

import org.japril.jhut.framework.JhutTest;
import org.japril.jhut.framework.TestFactory;
import org.japril.jhut.framework.test.SimulateForestFactory;
import org.japril.jutil.logging.Log;
import org.japril.jutil.logging.LogSink;
import org.japril.swing.TestFrame;
import org.japril.swing.jutil.logging.ControlLogSinkPanel;
import org.japril.swing.jutil.logging.ControlLogSinks;
import org.japril.swing.jutil.logging.ControlLogSinksDialog;
import org.japril.swing.jutil.logging2.ControlLogSinkDialog;

/**
 * <p>
 *   Swing applications for running 
 *   {@link JhutTest} tests.
 * </p>
 * @author Arne Halvorsen (AH)
 */
@SuppressWarnings("serial")
public final class TestTreeManager extends JFrame
{
  private final TestFactory m_factory;
  
  private final JTabbedPane m_tabs=new JTabbedPane();
  
  /**
   * <p>
   *   Constructor.
   * </p>
   * @param f {@link TestFactory} to create tests.
   */
  private TestTreeManager(TestFactory f){ this(f, false); }
  
  /**
   * <p>
   *   Constructor.
   * </p>
   * @param f       {@link TestFactory} to create tests.
   * @param logging {@code true} if to give access to logging admin.
   */
  private TestTreeManager(TestFactory f, boolean logging)
  {
    if (f==null)
    {
      throw new NullPointerException("f");
    }
    
    setTitle("Testing: "+f.getName());
    
    m_factory=f;
    
    Container c=getContentPane();
    c.setLayout(new BorderLayout());
    
    c.add(m_tabs, BorderLayout.CENTER);
    
    JToolBar tb=createToolBar(logging);
    c.add(tb, BorderLayout.NORTH);
    
    createMenuBar();
    createTabs();
    
    pack();
    setSize(500, 500);
    setVisible(true);
    
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  }
  
  // Menu system
  
  private void createMenuBar()
  {
    JMenuBar menuBar=new JMenuBar();
    
    JMenu fileMenu=createFileMenu();
    menuBar.add(fileMenu);
    
    setJMenuBar(menuBar);
  }
  
  private JMenu createFileMenu()
  {
    JMenu retVal=new JMenu("File");
    
    retVal.add(m_closeAction);
    
    return retVal;
  }
  
  private final Action m_closeAction=new AbstractAction("Close")
  {
    public void actionPerformed(ActionEvent e)
    {
      System.exit(0);
    }
  };
  
  // Toolbar.
  
  private JToolBar createToolBar(boolean logging)
  {
    JToolBar retVal=new JToolBar();
    
    retVal.add(m_resetAction);
    if (logging) retVal.add(m_loggingAdminAction);
    
    return retVal;
  }
  
  private final Action m_resetAction=new AbstractAction("Reset")
  {
    public void actionPerformed(ActionEvent e) 
    {
      createTabs();
    }
  };
  
  private ControlLogSinkDialog m_logDlg=null;
  
  private final Action m_loggingAdminAction=new AbstractAction("Logging")
  {
    public void actionPerformed(ActionEvent e)
    {
      if (m_logDlg==null) m_logDlg=new ControlLogSinkDialog();
      m_logDlg.showDialog();
      
      /*
      //LogSink ls=Log.getLogSink();
      ControlLogSinkPanel dlsp=new ControlLogSinkPanel();
      //dlsp.setSink(ls);
      TestFrame.show(dlsp);
      */
    }
  };
  
  // Tabs.
  
  private void createTabs()
  {
    m_tabs.removeAll();
    
    List<String> wnames=m_factory.getWorldNames();
    
    if (wnames.isEmpty())
    {
      createTab(m_factory.getName(), m_factory, null);
    }
    else
    {
      for (String wname : wnames)
      {
        createTab(wname, m_factory, wname);
      }
    }
  }
  
  private void createTab(String name, TestFactory tf, String wname)
  {
    List<JhutTest> forest=m_factory.createTests();
    
    TestTreeManagerPanel ttmp=new TestTreeManagerPanel(forest, tf, wname);
 
    m_tabs.addTab(name, ttmp);
  }
  
  /**
   * <p>
   *   Shows application for tests given factory creates.
   * </p>
   * @param f       Factory to create tests.
   * @param perform {@code true} if to perform test as part of launching 
   *                application.
   * @param logging {@code true} if to give access to logging admin. 
   */
  public static void show(final TestFactory f, final boolean perform, 
    final boolean logging)
  {
    if (f==null)
    {
      throw new NullPointerException("f");
    }
    
    SwingUtilities.invokeLater
    (
      new Runnable()
      { 
        public void run()
        { 
          TestTreeManager ttm=new TestTreeManager(f, logging);
          ttm.setVisible(true);         
        }
      }
    );
  }
  
  /**
   * <p>
   *   Test program.
   * </p>
   * @param args Command line 
   */
  public static void main(String[] args) 
  {
    ControlLogSinks.getInstance().getCurrent();
    show(new SimulateForestFactory(), false, false);
  }
  
}
